package com.example.datacore

import android.content.Context
import com.example.sourceslibs.CarManagerImpl
import com.example.sourceslibs.ICarManager
import com.example.sourceslibs.SignalType
import dagger.Binds
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.android.qualifiers.ApplicationContext
import dagger.hilt.components.SingletonComponent
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.abs


data class Event(
    val id:Long,
    val name:String,
    val value:Int,
)

interface IBCMRepository {

    fun <T> getStateFlow(signalList:SignalType): StateFlow<T?>

    fun  getEventFlow(signalList:List<SignalType>): SharedFlow<Event?>

    suspend fun changeState(signalType: SignalType, state: Any): Result<Boolean>
}

interface IEventRepository {
    fun getEventFlow(): SharedFlow<Event?>
}

@Module
@InstallIn(SingletonComponent::class)
object RepositoryScopeProvider {
    @Provides
    @RepositoryScope
    fun provideRepositoryScope() = CoroutineScope(Dispatchers.IO)
}


/**
 * 信号的全量仓库
 * 仅能在 当前数据层使用
 * internal 限定符 只能在当前模块使用
 * */
class BCMRepositoryImpl @Inject constructor(
    private val carManager: ICarManager,
    @RepositoryScope
    private val repositoryScope:CoroutineScope,
    @ApplicationContext
    private val context: Context
) : IBCMRepository {
    companion object{
        const val SKY_WIN_CLOSED = 0
        const val SKY_WIN_OPENING = 1
        const val SKY_WIN_STOP = 2
        const val SKY_WIN_CLOSING =3
        const val SKY_WIN_OPENED =5
    }

    private val _fullSignalStateFlowMap:MutableMap<SignalType,MutableStateFlow<Any?>> = mutableMapOf()


    init {
        _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_POS] = MutableStateFlow(50)
        _fullSignalStateFlowMap[SignalType.CAR_TAIL_GATE_POS] = MutableStateFlow(100)
        _fullSignalStateFlowMap[SignalType.CAR_VEHICLE_GEAR] = MutableStateFlow(1)
        _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_STATE] = MutableStateFlow(0)
    }

    override fun <T> getStateFlow(signalType: SignalType): StateFlow<T?> {
        return (_fullSignalStateFlowMap.get(signalType) as MutableStateFlow<T>).asStateFlow()
    }


    override fun getEventFlow(signalList: List<SignalType>): SharedFlow<Event?> {
        TODO("Not yet implemented")
    }


    override suspend fun changeState(signalType: SignalType, state: Any): Result<Boolean> {
        delay(50)
        when(signalType){
            SignalType.CAR_SKY_WINDOW_POS->{
                repositoryScope.launch {

                    val targetPos = state as Int
                    //当前位置
                    val curPos = _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_POS]?.value as Int

                    if (targetPos!=0 && targetPos !=100) {
                        _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_STATE]?.emit(
                            SKY_WIN_OPENING)
                    }else if (curPos>targetPos){
                        _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_STATE]?.emit(
                            SKY_WIN_CLOSING)
                    }else{
                        _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_STATE]?.emit(
                            SKY_WIN_OPENING)
                    }
                    //模拟运行耗时
                    delay(2000)

                    when(targetPos){
                        0->{//关闭
                            _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_STATE]?.emit(
                                SKY_WIN_CLOSED)
                            _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_POS]?.emit(
                                0)
                        }
                        100->{//打开
                            _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_STATE]?.emit(
                                SKY_WIN_OPENED)
                            _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_POS]?.emit(
                                100)
                        }
                        else->{//停止
                            _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_STATE]?.emit(
                                SKY_WIN_STOP)
                            _fullSignalStateFlowMap[SignalType.CAR_SKY_WINDOW_POS]?.emit(
                                targetPos)
                        }
                    }

                }

            }
            else->{
                //do nothing
            }
        }


//        if (carManager.setSignalForObject(signalType,state)) {
//            return Result.success(true)
//        }
        return Result.failure(Throwable("changeState failed"))
    }

}

@Module
@InstallIn(SingletonComponent::class)
abstract class TailGateRepositoryModule{
    @Binds
    @Singleton
    abstract fun createRepository(impl:BCMRepositoryImpl):IBCMRepository

}


@Module
@InstallIn(SingletonComponent::class)
object CarManagerProvider{
    @Provides
    @Singleton
    fun createRepository():ICarManager = CarManagerImpl()
}